import {Injectable} from '@angular/core';
import {HttpService} from '@kylin/http';
import {NzMessageService, NzModalService} from 'ng-zorro-antd';
import {BtnInfo} from './buttons/interface';
import {RequestInfo} from './interface';
import {ConfigService} from '@kylin/config';
import {BatchedModalComponent} from './other/batched-modal/batched-modal.component';
import {
    HttpClient,
    HttpEvent,
    HttpHeaders,
    HttpEventType,
    HttpRequest,
    HttpResponse
} from '@angular/common/http';


export class BatchedOption {
    operation?: string;
    reqInfo?: RequestInfo;
    idProp?: string;
    reqProp?: string;
    operable?: (item, index, list, funSet) => boolean;
    title?: string;
}

@Injectable()
export class PredefineForProjectService {
    constructor(private http: HttpService,
                private message: NzMessageService,
                private modalService: NzModalService,
                private config: ConfigService,
                private httpClient: HttpClient) {
    }

    private sendRequest(reqInfo: RequestInfo, reqParams) {
        return this.http[reqInfo.method.toLowerCase()](reqInfo.path, reqParams)
    }

    private getValsByIdProp(idProp: string, data: any[], targetType?: 'string' | 'array') {
        targetType = targetType || 'array'; // 返回格式 字符串 or 数组
        let rst = [] as any;
        rst = data.map(item => item[idProp] || '');
        if (targetType === 'string') {
            return rst.join(',');
        } else {
            return rst;
        }
    }

    /**
     *  生成 导出按钮
     * @param reqInfo
     * @param params
     * @param idProp 每条数据中将向后台发送的字段名称，如：ID
     */
    getExport = (options: BatchedOption): BtnInfo => {
        const {operation, reqInfo, idProp, reqProp, operable} = options;
        return {
            name: operation || '导出数据',
            klClick: (data, funSet) => {
                let reqParams;
                data = operable ? data.filter((item, index) => operable(item, index, data, funSet)) : data;
                if (data && data.length) {
                    // 导出勾选的项
                    reqParams = {
                        ...({[reqProp]: this.getValsByIdProp(idProp, data, 'string')})
                    };
                } else {
                    // 导出当前条件下所有项
                    reqParams = {
                        ...(funSet.getSelected()),
                        ...(funSet.getCurSortInfo())
                    };
                }
                this.sendRequest(reqInfo, {...reqParams, ...(reqInfo.params), ...(funSet.getCurrentStatus)}).then(rep => {
                    if (rep.status === 200) {
                        const eleLink = document.createElement('a');
                        eleLink.download = '';
                        eleLink.style.display = 'none';
                        eleLink.href = this.config.imgHostname + rep.result;
                        document.body.appendChild(eleLink);
                        eleLink.click();
                        document.body.removeChild(eleLink);
                    } else {
                        this.message.error(`导出失败：${rep.message}`);
                    }
                });
            }
        }
    };

    /**
     * 生成批量删除按钮
     * @param reqInfo 删除对应request 信息
     * @param params 删除所需的其他参数
     * @param idProp  每条数据中将向后台发送的字段名称，如：ID
     * @param operable 判断数据中某项是否可删除，true可以
     */
    getBatchedDelete(options): BtnInfo {
        const {title} = options;
        options.operation = '批量删除';
        const btnInfo: BtnInfo = this.getBatchedDo(options);
        btnInfo.disableOnNoRst = true;
        btnInfo.bindChecked = true;
        btnInfo.confirm = {
            title: title || `仅“待提交”状态的信息将被处理，确认删除?`
        };
        return btnInfo;
    }

    /** 批量提交 **/
    getBatchedSubmit(options): BtnInfo {
        const {title} = options;
        options.operation = '批量提交';
        const btnInfo: BtnInfo = this.getBatchedDo(options);
        btnInfo.disableOnNoRst = true;
        btnInfo.bindChecked = true;
        btnInfo.confirm = {
            title: title || '仅“待提交”状态的信息将被处理，确认提交?'
        };
        return btnInfo;
    }

    /** 批量导入 **/
    getBatchedImport(options): BtnInfo {
        const {operation, reqInfo, downloadPath, accept} = options;
        const btnInfo = new BtnInfo();
        Object.assign(btnInfo, {
            name: operation || '批量导入',
            klClick: (data, funSet) => {
                this.modalService.create({
                    nzTitle: '导入数据',
                    nzContent: BatchedModalComponent,
                    nzComponentParams: {
                        downloadPath,
                        importReqInfo: reqInfo,
                        btnInfo,
                        funSet,
                        accept
                    },
                    nzFooter: null
                });
            }
        });
        return btnInfo;
    }

    getBatchedDo(options) {
        const {operation, reqInfo, idProp, reqProp, operable} = options;
        return {
            name: operation,
            klClick: (data, funSet) => {
                const operableData = operable ? data.filter((item, index) => operable(item, index, data, funSet)) : data;
                if (reqInfo.method.toLowerCase() === 'delete') {
                    const reqParams = this.getValsByIdProp(idProp, operableData, 'string');
                    const path = reqInfo.path + `?${reqProp}=${reqParams}`;
                    this.sendRequest({path, method: 'delete'} as any, null).then(rep => {
                        if (rep.status === 200) {
                            this.message.success(`${operation}成功`);
                            funSet.refreshList();
                        } else {
                            this.message.error(`${operation}失败：${rep.message}`);
                        }
                    });
                } else {
                    const reqParams = this.getValsByIdProp(idProp, operableData);
                    this.sendRequest(reqInfo, {[reqProp]: reqParams, ...(reqInfo.params)}).then(rep => {
                        if (rep.status === 200) {
                            this.message.success(`${operation}成功`);
                            funSet.refreshList();
                        } else {
                            this.message.error(`${operation}失败：${rep.message}`);
                        }
                    });
                }
            }
        };
    }
}
